package com.richrail.gui;

import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.Graphics;

import javax.swing.JPanel;

import com.richrail.Depot;
import com.richrail.state.DepotState;
import com.richrail.state.TrainState;
import com.richrail.state.WagonState;
import com.richrail.util.Observable;
import com.richrail.util.Observer;

public class GraphicView extends JPanel implements View, Observer
{
	private static final long serialVersionUID = 1L;
	
	private static int OFFSET = 100;
	
	private DepotState depotState;
	
	public GraphicView()
	{
		this.setBackground(Color.WHITE);
	}
	
	public void resolvePreferredSize()
	{
		if (depotState != null)
		{
			int maxWagons = 0;
			for (TrainState trainState: depotState.getTrains())
			{
				int wagonCount = trainState.getWagons().size();
				if (wagonCount > maxWagons) maxWagons = wagonCount;
			}
			// 1 = for the train.
			this.setPreferredSize(new Dimension(10 + (1 + maxWagons) * OFFSET, 40 + depotState.getTrains().size() * OFFSET));
		}
	}
	
	@Override
	public void paintComponent(Graphics g)
	{
		super.paintComponent(g);
		
		if (depotState != null)
		{
			int trainPos = 0;
			for (TrainState trainState: depotState.getTrains())
			{
				paintTrain(g, trainState, trainPos);
				
				int wagonPos = 0;
				for (WagonState wagonState: trainState.getWagons())
				{
					paintWagon(g, wagonState, trainPos, ++wagonPos);
				}
				trainPos++;
			}
		}
	}
	
	public void paintTrain(Graphics g, TrainState trainState, int trainPos)
	{
		g.setColor(Color.LIGHT_GRAY);
		g.fillRect(30, 80 + trainPos * OFFSET, 80, 40);
		g.fillRect(80, 60 + trainPos * OFFSET, 30, 30);
		g.drawRoundRect(85, 40 + trainPos * OFFSET, 20, 20, 20, 20);
		g.drawRoundRect(85, trainPos * OFFSET, 40, 40, 40, 40);
		g.setColor(Color.BLACK);
		g.fillRoundRect(35, 120 + trainPos * OFFSET, 20, 20, 20, 20);
		g.fillRoundRect(80, 120 + trainPos * OFFSET, 20, 20, 20, 20);
		g.drawString(trainState.getName(), 40, 105 + trainPos * OFFSET);
	}
	
	public void paintWagon(Graphics g, WagonState wagonState, int trainPos, int wagonPos)
	{
		g.setColor(Color.LIGHT_GRAY);
		g.fillRect(30 + wagonPos * OFFSET, 80 + trainPos * OFFSET, 80, 40);
		g.setColor(Color.BLACK);
		g.fillRoundRect(35 + wagonPos * OFFSET, 120 + trainPos * OFFSET, 20, 20, 20, 20);
		g.fillRoundRect(80 + wagonPos * OFFSET, 120 + trainPos * OFFSET, 20, 20, 20, 20);
		g.drawString(wagonState.getName(), 40 + wagonPos * OFFSET, 105 + trainPos * OFFSET);
	}
	
	@Override
	public String getName()
	{
		return "Graphical";
	}
	
	@Override
	public void update(Observable observable)
	{
		if (observable instanceof Depot)
		{
			depotState = ((Depot) observable).getState();
			resolvePreferredSize();
			revalidate();
			repaint();
		}
	}
	
	@Override
	public Component toComponent()
	{
		return this;
	}
}
